package com.desire.homework;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 测试一下在文件中找单词重复次数的，一个面试题
 *
 * @author liweihan
 * @time 2016-12-28 16:48
 */
public class _40_统计txt文档单词数量 {

    public static void main(String[] args) throws Exception {
        // 正则比配 偏慢
        //display("C:\\Users\\desire\\Desktop\\javaProject\\01-javaBase\\src\\main\\resources\\srcjava.txt");
        // 稍好
        display2("C:\\Users\\desire\\Desktop\\javaProject\\01-javaBase\\src\\main\\resources\\srcjava.txt");
    }

    /**
     * @author liweihan
     * @time 2016/12/28 17:28
     * @description 方法1:正则，分割，map
     * 缺点：对标点符号没有办法区分？！
     */
    public static void display(String path) throws Exception {
        File file = new File(path);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line = null;
        //定义一个map集合保存单词和单词出现的个数
        TreeMap<String, Integer> tm = new TreeMap<String, Integer>();
        //读取文件
        while ((line = br.readLine()) != null) {
            line = line.toLowerCase();
            String reg1 = "\\s+";
            String reg2 = "\\w+";
            //将读取的文本进行分割
            String[] str = line.split(reg1);
            for (String s : str) {
                if (s.matches(reg2)) {
                    //判断集合中是否已经存在该单词，如果存在则个数加1，否则将单词添加到集合中，且个数置为1
                    if (!tm.containsKey(s)) {
                        tm.put(s, 1);
                    } else {
                        tm.put(s, tm.get(s) + 1);
                    }
                }
            }
        }
        br.close();

        System.out.println(tm);
        printResult(tm);
    }

    /**
     * @author liweihan
     * @time 2016/12/28 17:30
     * @description 方法2
     */
    public static void display2(String path) throws Exception {
        File file = new File(path);
        BufferedReader br = new BufferedReader(new FileReader(file));

        int tmpchar;
        StringBuilder exist = new StringBuilder();
        Map<String, Integer> map = new TreeMap<>();

        //读取文件 //读取单个字符
        while ((tmpchar = br.read()) != -1) {
            //字母
            if (isCharacter(tmpchar)) {
                exist.append((char) tmpchar);
            } else {
                addWord(exist.toString(), map);
                exist = new StringBuilder();
            }
        }
        br.close();
        System.out.println(map);
        printResult(map);
    }

    /**
     * @author liweihan
     * @time 2016/12/28 17:32
     * @description 判断是否为字母
     */
    public static boolean isCharacter(int tmpchar) {
        if (tmpchar >= 65 && tmpchar <= 90) {
            return true;
        } else {
            return tmpchar >= 97 && tmpchar <= 122;
        }
    }

    /**
     * @author liweihan
     * @time 2016/12/28 17:36
     * @description 把字母组合成单词, 并统计单词的数量
     */
    public static void addWord(String str, Map<String, Integer> map) {
        str = str.toLowerCase();
        map.merge(str, 1, Integer::sum);
    }

    /**
     * @param map
     * @author liweihan
     * @time 2016/12/28 18:34
     * @description 打印map集合的数据，并排序
     */
    public static void printResult(Map<String, Integer> map) {
        List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
        // .compareTo() 降序排序,当o2小于、等于、大于o1时，返回-1,0,1
        list.sort((o1, o2) -> (o2.getValue().compareTo(o1.getValue())));
        for (int i = 0; i < 50; i++) {
            Map.Entry<String, Integer> entry = list.get(i);
            if (entry == null) {
                return;
            }
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }
}
